#ifndef BOOST_ASYNC_SOCKET_H__
#define BOOST_ASYNC_SOCKET_H__

#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/thread/condition.hpp>
#include <boost/signals2.hpp>
using namespace boost;
using namespace boost::asio;

#include <vector>
using namespace std;

typedef shared_ptr<ip::tcp::socket> sock_pt;
typedef void(*PFUN)(sock_pt);
typedef unsigned int UINT;

class CBoostAsyncServerSocket
{
public:
	CBoostAsyncServerSocket(void);
	virtual ~CBoostAsyncServerSocket(void);

	void Init(UINT nPort);
	void Start();
	void Stop();
	void Run();
	void WaitForFinish();
	void RegisterFinishNotify(PFUN pFun);

	virtual void OnReceive(const system::error_code& nErrorCode,char* buf,int len,sock_pt sock);
//	virtual void OnConnect(const system::error_code& nErrorCode);
	virtual void OnSended(const system::error_code& nErrorCode,sock_pt sock);
	virtual void OnAccept(const system::error_code& nErrorCode,sock_pt sock);
	virtual void OnClose(const system::error_code& nErrorCode,sock_pt sock);

protected:
	void accept_handler(const system::error_code& ec, sock_pt sock);
	void read_handler(const system::error_code& ec, shared_ptr< vector<char> > str, sock_pt sock);
	void write_handler(const system::error_code& ec, sock_pt sock);
private:
	shared_ptr<ip::tcp::acceptor> m_acceptor;
	io_service m_ios;
	boost::mutex m_mutex;
	boost::condition m_cond;

	boost::signals2::signal<void(sock_pt)> m_sig;
};


class CBoostAsyncClientSocket
{
public:
	CBoostAsyncClientSocket();
	~CBoostAsyncClientSocket();

	bool Connect(const string& ip,UINT port=80);
//	void Start();
	void Stop();
	void Run();
	void WaitForFinish();
	void RegisterFinishNotify(PFUN pFun);


	virtual void OnReceive(const system::error_code& nErrorCode,char* buf,int len);
	virtual void OnConnect(const system::error_code& nErrorCode);
	virtual void OnSended(const system::error_code& nErrorCode);
	virtual void OnClose(const system::error_code& nErrorCode);

protected:
	void read_handler(const system::error_code& ec, shared_ptr< vector<char> > str);
	void write_handler(const system::error_code& ec);
	void connect_handler(const system::error_code& ec);
private:
	io_service m_ios;
	boost::mutex m_mutex;
	boost::condition m_cond;
	//ip::address m_addr;
	//UINT m_port;
	boost::signals2::signal<void(sock_pt)> m_sig;
	ip::tcp::endpoint m_ep;
	shared_ptr<ip::tcp::socket> m_connector;
};









#endif
